package top.zt9.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.qf.enums.InterfaceExceptionEnums;
import com.qf.exception.SmsException;
import com.qf.model.StandardReport;
import com.qf.model.StandardSubmit;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import top.zt9.service.ElasticsearchService;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author ztf
 * @Date 9:53 2021/11/27
 **/
@Service
@Slf4j
public class ElasticsearchServiceImpl implements ElasticsearchService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Value("${log-index}")
    private String index;

    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 保存日志到es
     *
     * @param standardSubmit
     */
    @Override
    public void saveLog(StandardSubmit standardSubmit) throws IOException {
        //获取索引名称
        String indexName = index + new SimpleDateFormat("yyyy").format(new Date());
        //request,设置indexName和根据standardSubmit的 唯一id设置id
        IndexRequest request = new IndexRequest();
        request.index(indexName);
        request.id(standardSubmit.getSequenceId());
        //封装
        request.source(objectMapper.writeValueAsString(standardSubmit), XContentType.JSON);
        //执行并获取结果
        IndexResponse indexResponse = restHighLevelClient.index(request, RequestOptions.DEFAULT);
        //根据结果判断是否成功,如果失败则抛出异常
        if (!indexResponse.getResult().toString().equalsIgnoreCase("created")){
            log.error("【搜索模块】添加日志 ， 添加日志失败 result = {},submit = {}",indexResponse.getResult().toString(),standardSubmit);
            throw new SmsException(InterfaceExceptionEnums.SEARCH_SAVE_LOG_ERROR);
        }

    }

    /**
     * 修改es中保存的数据
     *
     * @param standardreport
     */
    @Override
    public void updateLog(StandardReport standardreport) throws IOException {
        //获取索引名称
        String indexName = index + new SimpleDateFormat("yyyy").format(new Date());

        //request
        UpdateRequest request = new UpdateRequest();
        request.index(indexName);
        request.id(standardreport.getSequenceId());

        //封装
        Map<String,Object> source = new HashMap<>();
        source.put("reportState", standardreport.getState());
        source.put("errorCode", standardreport.getErrorCode());
        request.doc(source);

        //执行并获取结果
        UpdateResponse updateResponse = restHighLevelClient.update(request, RequestOptions.DEFAULT);

        //根据返回结果判断是否成功
        if (!updateResponse.getResult().toString().equalsIgnoreCase("update")){
            log.error("【搜索模块】修改日志 ， 修改日志失败 result = {},submit = {}",updateResponse.getResult().toString(),standardreport);
            throw new SmsException(InterfaceExceptionEnums.SEARCH_UPDATE_LOG_ERROR);
        }


    }

    /**
     * 查询日志条数
     *
     * @param param
     * @return
     */
    @Override
    public Long logsCount(Map param) throws IOException {

        //获取索引名称
        String indexName = index + new SimpleDateFormat("yyyy").format(new Date());

        //request
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices(indexName);

        //封装
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        //设置查询数据的条件 关键字、手机号、时间、公司（clientId）
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //1. 公司（clientId）
        Integer clientId = (Integer) param.get("clientId");
        if (clientId!=null){
            boolQueryBuilder.must(QueryBuilders.termQuery("clientId", clientId));
        }
        //关键字
        String keyword = (String) param.get("keyword");
        if (StringUtils.isEmpty(keyword)){
            boolQueryBuilder.must(QueryBuilders.termQuery("keyword", keyword));
        }

        //手机号
        String mobile = (String) param.get("mobile");
        if (StringUtils.isEmpty(mobile)){
            boolQueryBuilder.must(QueryBuilders.termQuery("mobile", mobile));
        }

        //时间
        Long startTime = (Long) param.get("startTime");
        Long endTime = (Long) param.get("endTime");

        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("sendTime");

        if(startTime!=null){
            rangeQueryBuilder.gte(startTime);
        }
        if(endTime!=null){
            rangeQueryBuilder.gte(endTime);
        }
        boolQueryBuilder.must(rangeQueryBuilder);

        // 设置sourceBuilder
        sourceBuilder.query(boolQueryBuilder);

        Integer start = (Integer) param.get("start");
        Integer rows = (Integer) param.get("rows");
        sourceBuilder.from(start);
        sourceBuilder.size(rows);

        searchRequest.source(sourceBuilder);

        //执行查询并返回结果
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        long count = searchResponse.getHits().getTotalHits().value;


        return count;
    }
}
